 package com.gzhryc.weixin.gzh;

 import com.gzhryc.common.DateTools;
 import com.gzhryc.common.json.JsonTools;
 import com.gzhryc.weixin.api.DefaultApiResponse;
 import com.gzhryc.weixin.gzh.models.AccessToken;
 import com.gzhryc.weixin.gzh.models.JSSDKConfig;
 import com.gzhryc.weixin.gzh.msg.JSSDKTicketResponse;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.http.HttpEntity;
 import org.apache.http.client.methods.CloseableHttpResponse;
 import org.apache.http.client.methods.HttpGet;
 import org.apache.http.client.utils.URIBuilder;
 import org.apache.http.impl.client.CloseableHttpClient;
 import org.apache.http.impl.client.HttpClients;
 import org.apache.http.util.EntityUtils;
 import org.apache.log4j.Logger;

 import java.io.IOException;
 import java.io.UnsupportedEncodingException;
 import java.net.URI;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.util.Date;
 import java.util.Formatter;
 import java.util.UUID;

/**
 * 微信JSSDK服务
 * @author 张浩
 *
 */
public class WxJSSDKApi extends AbsWeixinApi{
	
	static final Logger log = Logger.getLogger(WxJSSDKApi.class);
	
	public JSSDKTicketResponse ticketResponse;
	public Date getTicketDate;
	
	public WxJSSDKApi(AccessToken accessToken) {
		super(accessToken);
	}

	public String getTicket(){
		if(isExpire()){
			ticketResponse = getTicketResponse();
		}
		if(ticketResponse != null) {
			return ticketResponse.getTicket();
		}
		return "";
	}
	
	/**
	 * 获取JSSDK配置
	 * @param url
	 * @return
	 */
	public JSSDKConfig getConfig(String url){
		JSSDKConfig config = new JSSDKConfig();
		try{
			config.setAppId(accessToken.getAppid());
			config.setNonceStr(createNonceStr());
			config.setTimestamp(createTimestamp());
			config.setUrl(url);
			
			String string1 = "jsapi_ticket=" + getTicket() +
	                "&noncestr=" + config.getNonceStr() +
	                "&timestamp=" + config.getTimestamp() +
	                "&url=" + url;
		
            MessageDigest crypt = MessageDigest.getInstance("SHA-1");
            crypt.reset();
            crypt.update(string1.getBytes("UTF-8"));
            config.setSignature(byteToHex(crypt.digest()));
        } catch (NoSuchAlgorithmException e){
            e.printStackTrace();
        } catch (UnsupportedEncodingException e){
            e.printStackTrace();
        } catch(Exception e){
        	e.printStackTrace();
        }
		
		return config;
	}
	
	public JSSDKTicketResponse getTicketResponse(){
		CloseableHttpResponse response = null;
		try {
			getTicketDate = new Date(); //设置获取ticket的时间
			CloseableHttpClient httpclient = HttpClients.createDefault();
			URI uri = new URIBuilder()
		        .setScheme("https")
		        .setHost("api.weixin.qq.com")
		        .setPath("/cgi-bin/ticket/getticket")
		        .setParameter("access_token",accessToken.getAccess_token())
		        .setParameter("type","jsapi")
		        .build();
			HttpGet httpget = new HttpGet(uri);
			response = httpclient.execute(httpget);
			HttpEntity entity = response.getEntity();
			if(entity != null){
				String str = EntityUtils.toString(entity);
				if(StringUtils.isNotBlank(str)){
					log.debug("getTicketResponse result:"+str);
					JSSDKTicketResponse resp = JsonTools.fromJson(str, JSSDKTicketResponse.class);
					if(resp.getErrcode() == 0) {
						return resp;
					}else {
						log.debug("触发错误：" + resp.getErrcode()+"，APPID = "+accessToken.getAppid() + ", access_token = " +accessToken.getAccess_token());
						DefaultApiResponse defApiResp = new DefaultApiResponse();
						defApiResp.setErrcode(resp.getErrcode());
						defApiResp.setErrmsg(resp.getErrmsg());
						accessToken.queuePut(defApiResp);
					}
				}
			}
		} catch(Exception e){
			log.error("getAccessToken error", e);
		} finally {
			if(response != null){
				try {
					response.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return null;
	}
	
	private String createNonceStr() {
        return UUID.randomUUID().toString();
    }

    private Long createTimestamp() {
        return System.currentTimeMillis() / 1000;
    }
    
    private String byteToHex(final byte[] hash) {
        Formatter formatter = new Formatter();
        for (byte b : hash)
        {
            formatter.format("%02x", b);
        }
        String result = formatter.toString();
        formatter.close();
        return result;
    }
    
    /**
     * 是否已过期
     * @return
     */
    private boolean isExpire(){
		if(ticketResponse != null && getTicketDate != null && ticketResponse.getExpires_in() != null){
			if(DateTools.differenceSecond(getTicketDate, new Date()) 
					< ticketResponse.getExpires_in()){
				return false;
			}
		}
		return true;
	}
}
